﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace StrategyGame
{
    class SideBar
	{
		#region Static resources
		static public readonly int Width = 200;

		static private SpriteFont HeaderFont;
        static private SpriteFont InfoFont;

		static public void LoadContent(ContentManager content)
		{
			HeaderFont = content.Load<SpriteFont>("fonts/MediumFont");
            InfoFont = content.Load<SpriteFont>("fonts/SmallFont");
		}
		#endregion

		#region Minimap generation
		private Texture2D MinimapTexture;

        public void RegenerateMinimap(GraphicsDevice device, TileMap map, Nation player_nation)
        {
            MinimapTexture = new Texture2D(device, map.Width, map.Height);
            
            Color[] texels = new Color[map.Width * map.Height];

            for (int u = 0;
                u < map.Width;
                ++u)
            {
                for (int v = 0;
                    v < map.Height;
                    ++v)
                {
                    int index = (v * map.Width) + u;

                    if (!player_nation.HasRevealedTile(u, v))
                        texels[index] = Color.Black;
                    else if (map.CityAtTile(u, v) != null)
                    {
                        texels[index] = map.FindOwnerOfCity(map.CityAtTile(u, v)).NationalColor;
                    }
                    else
                    {
                        switch (map.LookupTile(u, v))
                        {
                            case TileMap.TileType.Ice:
								texels[index] = Color.White;
								break;
							case TileMap.TileType.Tundra:
								texels[index] = Color.DarkGray;
								break;
							case TileMap.TileType.Arctic:
								texels[index] = Color.Snow;
								break;
							case TileMap.TileType.Shore:
								texels[index] = Color.LightBlue;
								break;
							case TileMap.TileType.Forest:
								texels[index] = Color.ForestGreen;
								break;
							case TileMap.TileType.Jungle:
								texels[index] = Color.LimeGreen;
								break;
							case TileMap.TileType.Desert:
                                texels[index] = Color.Tan;
                                break;
                            case TileMap.TileType.Grassland:
                                texels[index] = Color.DarkGreen;
                                break;
                            case TileMap.TileType.Mountains:
                                texels[index] = Color.Silver;
                                break;
                            case TileMap.TileType.Ocean:
                                texels[index] = Color.Navy;
                                break;
                        }

                        if (!player_nation.CanSeeTile(u, v))
                        {
                            texels[index] = Color.Multiply(texels[index], 0.4f);
                            texels[index].A = 255;
                        }
                    }
                }
            }

            MinimapTexture.SetData(texels);
        }
		#endregion

		#region Rendering
		public void Draw(SpriteBatch sprites, GraphicsDevice graphics, int turn_number, TileMap map, Nation playernation, Point camera_pos)
        {
            //draw the main colored rectangle of the bar
			Rectangle position = new Rectangle();
			position.Width = Width;
			position.Height = graphics.ScissorRectangle.Height;
				
			position.X = graphics.ScissorRectangle.Width - position.Width;
			position.Y = 0;

            Color bar_color = Color.Multiply(playernation.NationalColor, 0.5f);
            bar_color.A = 255;
			SpriteRectangle.Draw(sprites, position, bar_color);

			string turn_counter = playernation.Name + " - Turn: " + turn_number.ToString();
			Vector2 turn_counter_size = HeaderFont.MeasureString(turn_counter);
			
			float turnlabel_margin = 4; //distance from edge of screen
			float turn_counter_x = position.X + (Width/2 - turn_counter_size.X/2); //width of window minus width of string
			float turn_counter_y = turnlabel_margin; //same for height - puts it in the bottom right
			Vector2 turn_counter_pos = new Vector2(turn_counter_x - turnlabel_margin, turn_counter_y);

			TextUtils.DrawWithDropShadow(sprites, HeaderFont, turn_counter, turn_counter_pos, Color.White, Color.Black, 1);

            Rectangle minimap_rect = new Rectangle();
            int minimap_pos = (int)turn_counter_size.Y + (int)turnlabel_margin;
            int minimap_padding = 3;

            minimap_rect.X = position.X + minimap_padding;
            minimap_rect.Y = minimap_pos + minimap_padding;
            minimap_rect.Width = position.Width - (minimap_padding * 2);
            minimap_rect.Height = 180;

            DrawMiniMap(sprites, map, minimap_rect, camera_pos);

            Rectangle unitinfo_rect = new Rectangle();
            unitinfo_rect.X = minimap_rect.X;
            unitinfo_rect.Width = minimap_rect.Width;

            unitinfo_rect.Y = minimap_rect.Bottom + minimap_padding;
            unitinfo_rect.Height = 200;

            DrawUnitInfo(sprites, playernation, unitinfo_rect);
        }

        private void DrawUnitInfo(SpriteBatch sprites, Nation nation, Rectangle draw_rect)
        {
            Color darker_nationalcolor = Color.Multiply(nation.NationalColor, 0.1f);
            darker_nationalcolor.A = 255;

            SpriteRectangle.Draw(sprites, draw_rect, darker_nationalcolor);
            SpriteRectangle.DrawOutline(sprites, draw_rect, Color.Silver, 1);

            //show info about the current unit (todo: move this to an info panel class of some kind)
            string unit_info;
            Unit active_unit = nation.ActiveUnit;

            if (active_unit != null)
            {
                unit_info = "Active: " + active_unit.Name;
                unit_info += "\nMoves remaining: " + active_unit.GetRemainingMovePoints() + "/" + active_unit.GetMaxMovePoints();
            }
            else
                unit_info = "No unit selected";

            TextUtils.DrawWithDropShadow(sprites, InfoFont, unit_info, new Vector2(draw_rect.X + 4, draw_rect.Y + 4), Color.White, Color.Black, 2);
        }

        private void DrawMiniMap(SpriteBatch sprites, TileMap map, Rectangle minimap_rect, Point camera_pos)
        {
            SpriteRectangle.Draw(sprites, minimap_rect, Color.Black);
            SpriteRectangle.DrawOutline(sprites, minimap_rect, Color.Silver, 1);

            Rectangle minimap_inner_area = new Rectangle();
            minimap_inner_area.X = minimap_rect.X + 1;
            minimap_inner_area.Y = minimap_rect.Y + 1;
            minimap_inner_area.Width = minimap_rect.Width - 2;
            minimap_inner_area.Height = minimap_rect.Height - 2;

            if (MinimapTexture != null)
            {
                sprites.Draw(MinimapTexture, minimap_inner_area, Color.White);
            }

            int viewable_area_width = map.ScreenWidth / map.TileWidth;
            int viewable_area_height = map.ScreenHeight / map.TileHeight;

            float minimap_h_scale = minimap_rect.Width / (float)map.Width;
            float minimap_v_scale = minimap_rect.Height / (float)map.Height;

            Rectangle view_area_rect = new Rectangle();

            view_area_rect.X = camera_pos.X - (viewable_area_width / 2);
            view_area_rect.Width = viewable_area_width;
            view_area_rect.Y = camera_pos.Y - (viewable_area_height / 2);
            view_area_rect.Height = viewable_area_height;

            view_area_rect.X = minimap_rect.X + (int)(view_area_rect.X * minimap_h_scale);
            view_area_rect.Width = (int)(view_area_rect.Width * minimap_h_scale);
            view_area_rect.Y = minimap_rect.Y + (int)(view_area_rect.Y * minimap_v_scale);
            view_area_rect.Height = (int)(view_area_rect.Height * minimap_v_scale);

            SpriteRectangle.DrawOutline(sprites, view_area_rect, new Color(1.0f, 1.0f, 1.0f, 0.4f), 1);
        }
		#endregion

		public SideBar(GraphicsDevice graphics)
		{
			//not much to do here.. the sidebar doesn't really do anything itself, it just displays information about other parts of the game
		}
    }
}
